package com.weightx.weight.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.weightx.weight.common.HttpUtils;
import com.weightx.weight.common.JwtUtil;
import com.weightx.weight.common.R;
import com.weightx.weight.entity.*;
import com.weightx.weight.mapper.AdminMapper;
import com.weightx.weight.properties.WeixinProperties;
import com.weightx.weight.service.IAdviceService;
import com.weightx.weight.service.IDataService;
import com.weightx.weight.service.IUserService;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RequestMapping
@RestController
public class UserController {

    @Autowired
    private IUserService userService;

    @Autowired
    private IDataService dataService;

    @Autowired
    private IAdviceService adviceService;

    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private JwtUtil jwtUtil;

    private final WeixinProperties weixinProperties;
    public UserController(WeixinProperties weixinProperties){
        this.weixinProperties = weixinProperties;
    }

    @RequestMapping("/openid")
    public R login(@RequestBody LoginRequest request) {
        if (request.getCode() == null || request.getCode().isEmpty()) {
            return R.error();
        }
        try {
            //https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
//            HttpResponse response = HttpUtils.doGet("https://api.weixin.qq.com",
//                    "/sns/jscode2session?appid=wx2e0f0222477a962a&secret=1f0a8c20e5d16bc3eb29e1b429860d9f&js_code=" + request.getCode() + "&grant_type=authorization_code",
//                    "get",
//                    new HashMap<String, String>(),
//                    null);
            HttpResponse response = HttpUtils.doGet("https://api.weixin.qq.com",
                    "/sns/jscode2session?appid="+weixinProperties.getAppid()+"&secret="+weixinProperties.getAppSecret()+"&js_code=" + request.getCode() + "&grant_type=authorization_code",
                    "get",
                    new HashMap<String, String>(),
                    null);
            if (response.getStatusLine().getStatusCode() == 200) {
                String s = EntityUtils.toString(response.getEntity());
                WxResponse wxResponse = JSON.parseObject(s, WxResponse.class);
                System.out.println(wxResponse.toString());
                if (wxResponse != null && wxResponse.getOpenid() != null) {
                    return R.success(new LoginResponse(wxResponse.getOpenid()));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.error();

    }

    @RequestMapping("/sync")
    public R sync(@RequestBody SyncRequest syncRequest) {
        String openid = syncRequest.getOpenid();
        if (openid != null && !openid.isEmpty()) {
            user u = userService.getBaseMapper().selectOne(new QueryWrapper<user>().eq("openid", openid));
            if (u != null) {
                Long uid = u.getUserid();
                // 用户存在
                // 更新登录时间
                try {
                    u.setLoginTime(new Date());
                    userService.getBaseMapper().updateById(u);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                // 查找所有体重数据
                List<data> dataList = dataService.getBaseMapper().selectList(new QueryWrapper<data>().eq("userid", uid).orderByDesc("date"));
                dataList.forEach(it -> it.setDate2(com.weightx.weight.utils.DateUtils.formatDate(it.getDate())));
                SyncResponse response = new SyncResponse();
                response.setWeight(dataList);
                response.setUnit(u.getUnit());
                response.setBirth(u.getBirth() == null ? null : com.weightx.weight.utils.DateUtils.formatYear(u.getBirth()));
                response.setSex(u.getSex());
                response.setTargetWeight(u.getTargetWeight());
                response.setBodyHeight(u.getBodyHeight());
                return R.success(response);
            } else {
                // 用户不存在
                // 创建用户
                user nu = new user();
                nu.setOpenid(openid);
                nu.setRegisterTime(new Date());
                nu.setLoginTime(new Date());
                userService.getBaseMapper().insert(nu);
                return R.error(1001, "用户不存在");
            }
        }
        return R.error();
    }

    @RequestMapping("/advice")
    public R advice(@RequestBody AdviceRequest adviceRequest) {
        String openid = adviceRequest.getOpenid();
        String content = adviceRequest.getContent();
        if (openid == null || openid.isEmpty() || content == null || content.isEmpty()) {
            return R.error();
        }
        user u = userService.getBaseMapper().selectOne(new QueryWrapper<user>().eq("openid", openid));
        if (u != null) {
            Long uid = u.getUserid();
            // 用户存在
            Date today = com.weightx.weight.utils.DateUtils.getDateBefore(new Date(), 1);
            Long todayCount = adviceService.getBaseMapper().selectCount(new QueryWrapper<advice>().lambda().eq(advice::getUserid, uid).ge(advice::getDate, today));
            if (todayCount >= 5) {
                return R.error(1002, "每天只能提交5条建议");
            }
            advice advice = new advice();
            advice.setUserid(uid);
            advice.setContent(content);
            advice.setDate(new Date());
            adviceService.getBaseMapper().insert(advice);
            return R.success();
        }
        return R.error();
    }

    @RequestMapping("/unit")
    public R unit(@RequestBody UnitRequest request) {
        String openid = request.getOpenid();
        Integer content = request.getUnit();
        if (openid == null || openid.isEmpty() || content == null) {
            return R.error();
        }
        user u = userService.getBaseMapper().selectOne(new QueryWrapper<user>().eq("openid", openid));
        if (u != null) {
            // 用户存在
            u.setUnit(content);
            userService.getBaseMapper().updateById(u);
            return R.success();
        }
        return R.error();
    }

    @RequestMapping("/sex")
    public R sex(@RequestBody SexRequest request) {
        String openid = request.getOpenid();
        Integer content = request.getSex();
        if (openid == null || openid.isEmpty() || content == null) {
            return R.error();
        }
        user u = userService.getBaseMapper().selectOne(new QueryWrapper<user>().eq("openid", openid));
        if (u != null) {
            // 用户存在
            u.setSex(content);
            userService.getBaseMapper().updateById(u);
            return R.success();
        }
        return R.error();
    }

    @RequestMapping("/birthYear")
    public R birth(@RequestBody BirthRequest request) {
        String openid = request.getOpenid();
        String content = request.getBirthYear();
        if (openid == null || openid.isEmpty() || content == null) {
            return R.error();
        }
        try {
            Date date = DateUtils.parseDate(content, "yyyy");
            user u = userService.getBaseMapper().selectOne(new QueryWrapper<user>().eq("openid", openid));
            if (u != null) {
                // 用户存在
                u.setBirth(date);
                userService.getBaseMapper().updateById(u);
                return R.success();
            }
            return R.error();
        } catch (ParseException e) {
            return R.error();
        }

    }

    @RequestMapping("/bodyHeight")
    public R bodyHeight(@RequestBody BodyHeightRequest request) {
        String openid = request.getOpenid();
        Integer content = request.getBodyHeight();
        if (openid == null || openid.isEmpty() || content == null) {
            return R.error();
        }
        user u = userService.getBaseMapper().selectOne(new QueryWrapper<user>().eq("openid", openid));
        if (u != null) {
            // 用户存在
            u.setBodyHeight(content);
            userService.getBaseMapper().updateById(u);
            return R.success();
        }
        return R.error();
    }

    @RequestMapping("/targetWeight")
    public R targetWeight(@RequestBody TargetWeightRequest request) {
        String openid = request.getOpenid();
        Float content = request.getTargetWeight();
        if (openid == null || openid.isEmpty() || content == null) {
            return R.error();
        }
        user u = userService.getBaseMapper().selectOne(new QueryWrapper<user>().eq("openid", openid));
        if (u != null) {
            // 用户存在
            u.setTargetWeight(content);
            userService.getBaseMapper().updateById(u);
            return R.success();
        }
        return R.error();
    }

    @RequestMapping("/remind")
    public R remind(@RequestBody BaseRequest request) {
        String openid = request.getOpenid();
        if (openid == null || openid.isEmpty()) {
            return R.error();
        }
        user u = userService.getBaseMapper().selectOne(new QueryWrapper<user>().eq("openid", openid));
        if (u != null) {
            u.setRemind(1);
            userService.getBaseMapper().updateById(u);
            return R.success();
        }
        return R.error();
    }

    @RequestMapping("/loginManager")
    public R loginManager(@RequestBody ManagerLoginRequest request) {
        String username = request.getUsername();
        String password = request.getPassword();
        if (username == null || username.isEmpty() || password == null || password.isEmpty()) {
            return R.error();
        }
        admin a = adminMapper.selectOne(new QueryWrapper<admin>().lambda().eq(admin::getUsername, username));
        if (a != null && a.getPassword().equals(password)) {
            String token = jwtUtil.createToken(a.getId().longValue());
            return R.success(new ManagerLoginResponse(token));
        }
        return R.error();
    }

    @RequestMapping("/resetPassword")
    public R resetManager(@RequestBody ResetManagerRequest request) {
        String token = request.getToken();
        String oldPassword = request.getOldPassword();
        String newPassword = request.getNewPassword();
        if (token == null || token.isEmpty() || oldPassword == null || oldPassword.isEmpty() || newPassword == null || newPassword.isEmpty()) {
            return R.error();
        }
        Integer id = checkToken(token);
        if (id != null) {
            admin a = adminMapper.selectById(id);
            if (oldPassword.equals(a.getPassword())) {
                a.setPassword(newPassword);
                adminMapper.updateById(a);
                return R.success();
            }
        }

        return R.error();
    }

    private Integer checkToken(String token) {
        try {
            Claims claims = jwtUtil.parseToken(token);
            if (jwtUtil.judgeTokenExpiration(claims.getExpiration())) {
                return null;
            }
            Integer uid = Integer.valueOf(claims.getSubject());
            admin a = adminMapper.selectById(uid);
            if (a != null) {
                return a.getId();
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        return null;
    }


    @RequestMapping(value = "/getHistoryDatum")
    public R getHistoryDatum(@RequestBody SyncRequest syncRequest){
        String openid = syncRequest.getOpenid();
        HistoryDatumResponse hDResponse = new HistoryDatumResponse();
        if(openid != null && !openid.isEmpty()){
            user openid1 = userService.getBaseMapper().selectOne(new QueryWrapper<user>().eq("openid", openid));
            List<data> openid2 = dataService.getBaseMapper().selectList(new QueryWrapper<data>().eq("userid", openid1.getUserid()));
            hDResponse.setRegisterTime(openid1.getRegisterTime());
            hDResponse.setRecordNumber(openid2.size());
            return R.success(hDResponse);
        }else{
            return R.error();
        }
    }
}
